# @author: CaiJiaming
# @Time 2023/8/31 17:57

#引入操作系统内置库
import os,time,random,qrcode
from pystrich.ean13 import EAN13Encoder
#from string import digits

#初始化数据
number = '1234567890'
letter = 'ABCDEFGHIJKLMNOPQRSTTUVWXYZ1234567890'
# allis = '1234567890ABCDEFGHIJKLMNOPQRSTTUVWXYZabcdefghijklmnopqrstuvwxyz!@#$^&*()_+'
i = 0
randstr = []
# fourth = []
# fifth = []
randfir = ''
randsec = ''
# randthr = ''
# str_one = ''
# strone = ''
# strtwo = ''
# nextcard = ''
# userput = ''
# nrset_letter = ''



#创建文件夹函数
def mkdir(path):
    #判断目录路径是否存在
    isexists = os.path.exists(path)
    #目录路径不存在，则创建
    if not isexists:
        #创建目录
        os.mkdir(path)
#
# #读取文本文件
def openfile(filename):
    #打开文件
    f = open(filename)
    #读取文件内容
    flist = f.read()
    #关闭文件
    f.close()
    #返回读取的文件内容
    return flist

#输入验证判断函数
def inputbox(showstr,showorder,length):
    #输入提示文字
    intstr = input(showstr)
    if len(intstr) != 0:
        #三种验证方式

        #1：数字类型，不限位数
        if showorder == 1:
            #验证是否为数字
            if str.isdigit(intstr):
                if intstr == '0':
                    #输入的数字为0，要求重新输入
                    print("\033[1;31;40m输入为0，请重新输入!! \033[0m")
                    return '0'
                else:
                    #将输入的数字传递给函数的返回值
                    return intstr
            else:
                #输入的字符与要求的类型不符，判定为非法输入
                print("\033[1;31;40m输入非法请重新输入!! \033[0m")
                return '0'

        #2：要求字母格式且指定字母
        if showorder == 2:
            #判断输入的是否为字母
            if str.isalpha(intstr):
                #判断位数,与要求位数不匹配，重新输入
                if len(intstr) != length:
                    print("\033[1;31;40m请输入"+ str(length) + "个字母，请重新输入!! \033[0m")
                    return '0'
                else:
                    return intstr
            else:
                # 输入的字符与要求的类型不符，判定为非法输入
                print("\033[1;31;40m输入非法请重新输入!! \033[0m")
                return '0'

        #3：要求数字格式且有位数要求
        if showorder == 3:
            if str.isdigit(intstr):
                if len(intstr) != length:
                    print("\033[1;31;40m请输入" + str(length) + "个数字，请重新输入!! \033[0m")
                    return '0'
                else:
                    return intstr
            else:
                # 输入的字符与要求的类型不符，判定为非法输入
                print("\033[1;31;40m输入非法请重新输入!! \033[0m")
                return '0'
    else:
        print("输入为空，请重新输入")
        return "0"

#编码输出显示函数
def wfile(sstr,sfile,typeis,smsg,datapath):
    #生成目录
    mkdir(datapath)
    #设置保存防伪码的文件（包含路径）
    datafile = datapath + '/' + sfile
    #打开防伪码文件
    file = open(datafile,'w')
    wrlist = sstr
    pdata = ""
    wdata = ""
    for i in range(len(wrlist)):
        #去掉字符中的中括号
        wdata = str(wrlist[i].replace('[','')).replace(']','')
        #去掉字符中的引号
        wdata = wdata.replace("'",'').replace("'",'')
        #写入保存防伪码的文件
        file.write(str(wdata))
        #将单条防伪码存储到pdata变量
        pdata = pdata + wdata
    #关闭文件
    file.close()
    #屏幕输出生产的防伪码信息
    print("\033[1;31m"+ pdata +" \033[0m")
    #是否显示提示信息
    if typeis != 'no':
        print("提示",smsg + str(len(randstr))+",防伪码文件存放位置："+datafile)

#验证输入是否位数字
def input_validation(insel):
    if str.isdigit(insel):
        if insel == 0:
            print("\033[1;31;40m 非法输入，请重新输入！！\033[0m")
            return 0
        else:
            return int(insel)
    else:
        print("\033[1;31;40m 非法输入，请重新输入！！\033[0m")
        return 0

#生成6位防伪编码
def scode1(schoice):
    incount = inputbox("\033[1;32m 请输入您要生成防伪码的数量：\033[0m",1,0)
    #如果输入的数量是0，要求重新输入
    while incount == 0:
        incount = inputbox("\033[1;32m 请输入您要生成防伪码的数量：\033[0m", 1, 0)

    #清空保存批量防伪码信息的变量randstr
    randstr.clear()
    #根据输入的防伪码数量循环批量生成防伪码
    for j in range (int(incount)):
        #设置单条防伪码的变量为空
        randfir = ''
        for i in range(6):
            #产生数字的随机因子
            randfir = randfir + random.choice(number)
        randfir = randfir + '\n'
        randstr.append(randfir)

    #调用函数wfile(),实现生成的防伪码屏幕输出和文件输出
    wfile(randstr,"scode"+str(schoice)+".txt","","已生成6为防伪码共计：","codepath")

#生成9位系列产品防伪编码
def scode2(schoice):
    ordstart = inputbox("\033[1;32m 请输入系列产品的数字起始号（3位）：\033[0m",3,3)
    #如果输入的系列产品起始号不是三位数字，则要求重新输入
    while ordstart == 0:
        ordstart = inputbox("\033[1;32m 请输入系列产品的数字起始号（3位）：\033[0m", 3, 3)
    ordcount = inputbox("\033[1;32m 请输入产品系列的数量：",1,0)
    #如是果输入的产品系列数量小于1或大于9999,则要求重新输入
    while int(ordcount) < 1 or int(ordcount) > 9999:
        ordcount = inputbox("\033[1;32m 请输入产品系列的数量：", 1, 0)
    incount = inputbox("\033[1;32m 请输入要生成的每个系列产品的防伪码数量：\033[0m",1,0)
    while int(incount) == 0:
        incount = inputbox("\033[1;32m 请输入要生成的每个系列产品的防伪码数量：\033[0m", 1, 0)
    #清空保存的批量防伪码信息的变量randstr
    randstr.clear()
    #分类的产品防伪码编号
    for m in range(int(ordcount)):
        #产品防伪码编号
        for j in range(int(incount)):
            randfir = ''
            for i in range(6):
                randfir = randfir + random.choice(number)
            #生成的单条防伪码添加到防伪码列表
            randstr.append(str(int(ordstart) + m) + randfir + "\n")
    #调用wfile函数，实现生成的防伪码在屏幕输出和文件输出
    wfile(randstr,"scode"+str(schoice)+".txt","","已生成9位系列产品防伪码共计",'codepath')

#生成25位混合产品序列号
def scode3(schoice):
    incount = inputbox("\033[1;32m 请输入要生成的25位混合产品序列号数量：\033[0m",1,0)
    while int(incount) == 0:
        incount = inputbox("\033[1;32m 请输入要生成的25位混合产品序列号数量：\033[0m", 1, 0)
    #清空已保存防伪码信息列表
    randstr.clear()
    for j in range(int(incount)):
        strone = ''
        for i in range(25):
            strone = strone + random.choice(letter)
        strtwo = strone[0:5]+'-'+strone[5:10]+"-"+strone[10:15]+"-"+strone[15:20]+"-"+strone[20:25]+"\n"
        randstr.append(strtwo)
    #实现屏幕输出与文件输出
    wfile(randstr,"scode"+str(schoice)+".txt","","已生成2是5位混合防伪序列号码共计","codepath")

#生成含数据分析功能的防伪编码
def scode4(schoice):
    inptype = inputbox("\033[1;32m 请输入数据分析编号（3位字母）： \033[0m",2,3)
    while not str.isalpha(inptype) or len(inptype) != 3:
        inptype = inputbox("\033[1;32m 请输入数据分析编号（3位字母）： \033[0m,",2,3)

    #生成的防伪码数量
    incount = inputbox("\033[1;32m 输入要生成带分析功能的防伪编码的数量 \033[0m",1,0)
    while incount == 0:
        incount = inputbox("\033[1;32m 输入要生成带分析功能的防伪编码的数量 \033[0m",1,0)
    #调用生成防伪码函数
    ffcode(incount,inptype,"",schoice)

#生成含数据分许功能的防伪编码函数
#参数：scount 要生成的防伪码数量
#参数：typestr 数据分析字符
#参数：ismessage 提示信息字符
#参数：schoice 设置输出的文件名称
def ffcode(scount,typestr,ismessage,schoice):
    #清空保存的批量防伪码信息的变量
    randstr.clear()
    for j in range(int(scount)):
        #取第一个字母，区域分析码，并转换成大写
        strpro = typestr[0].upper()
        #取第二个字母，颜色分析码
        strtype = typestr[1].upper()
        #取第三字母，版本分析码
        strclass = typestr[2].upper()
        #随机抽取防伪码三个位置
        randfir = random.sample(number,3)
        #将位置排序返回给编码randsec
        randsec = sorted(randfir)
        #清空储存单条防伪码信息的变量
        letterone = ''
        for i in range(9):
            letterone = letterone + random.choice(number)
        #将三个字母分别插入防伪码中
        sim = str(letterone[0:int(randsec[0])]) + strpro + str(letterone[int(randsec[0]):int(randsec[1])]) + strtype + str(letterone[int(randsec[1]):int(randsec[2])]) + strclass + str(letterone[int(randsec[2]):9]) + "\n"
        #将防伪码存储到randstr变量中
        randstr.append(sim)

    #写入文件和输出屏幕
    wfile(randstr,typestr + "scode" + str(schoice)+".txt",ismessage,"生成带数据分析功能的防伪码共计：","codepath")

#智能批量生成带数据分析功能的防伪编码
def scode5(schoice):
    #读取文件
    with open("codeauto.txt",'r') as rfile:
        codelist = rfile.readlines()
    #批量生成
    for item in codelist:
        codea = item.split(",")[0]
        codeb = item.split(",")[1]
        ffcode(codeb,codea,"no",schoice)



#后续补加生成防伪编码
def scode6(choice):
    print("code6")

#批量生成条形码
def scode7():
    #输入国家码
    mainid = inputbox("\033[1;32m 请输入EN13的国家代码(3位)： \033[0m",1,0)
    while int(mainid) == 0:
        mainid = inputbox("\033[1;32m 请输入EN13的国家代码： \033[0m", 1, 0)
    #输入企业代码
    compid = inputbox("\033[1;32m 请输入企业代码（4位）： \033[0m",1,0)
    while int(compid) == 0:
        compid = inputbox("\033[1;32m 请输入企业代码（4位）： \033[0m",1,0)
    #生成条形码数量
    incount = inputbox("\033[1;32m 请输入要生成条形码的数量：： \033[0m",1,0)
    while int(incount) == 0:
        incount = inputbox("\033[1;32m 请输入要生成条形码的数量：\033[0m", 1, 0)
    #生成条形码目录
    mkdir("barcode")
    #循环生成条码
    for j in range(int(incount)):
        strone = ''
        for i in range(5):
            strone = strone + str(random.choice(number))

        #12位条形码
        barcode = mainid + compid + strone
        #计算条形码的校验码
        evensum = int(barcode[1]) + int(barcode[3]) + int(barcode[5]) + int(barcode[7]) + int(barcode[9]) + int(barcode[11])
        oddsum = int(barcode[0]) + int(barcode[2]) + int(barcode[4]) + int(barcode[6]) + int(barcode[8]) + int(barcode[10])
        checkbit = int((10 - ((evensum * 3 + oddsum) % 10)) % 10)
        #组成完整的ENA13条形码的13位数字
        barcode = barcode + str(checkbit)
        #调用EAN13Encoder生成条形码
        encoder = EAN13Encoder(barcode)
        #保存成图片
        encoder.save('barcode/'+str(barcode)+'.png')



#批量生成二维码
def scode8(choice):
    #输入要生成二维码的数量
    incount = inputbox("\033[1;32m 请输入要生成的12位数字的二维码数量： \033[0m",1,0)
    while int(incount) == 0:
        incount = inputbox("\033[1;32m 请输入要生成的12位数字的二维码数量： \033[0m", 1, 0)
    #判断存放二维码目录是否存在，不存在则创建qrcode目录
    mkdir("qrcode")
    #批量生成二维码
    for i in range(int(incount)):
        strone = ''
        for j in range(12):
            strone = strone + str(random.choice(number))
        print(strone)
        #用qrcode第三方库生成二维码图片
        encoder = qrcode.make(strone)
        #保存二维码图片到指定目录中
        encoder.save("qrcode/" + strone + ".png")


#实现企业粉丝抽奖
def scode9(choice):
    print("code9")

def mainmenu():
    #输出选择菜单
    print("""\033[1;35m
        **************************************************************
                                企业编码生成系统
        **************************************************************
            1.生成6位数字防伪码（213563型）
            2.生成9位系列产品数字防伪编码（979-335439型）
            3.生成25位混合产品序列号（B2R12-N7TE8-9IET2-FE350-DW2K4型）
            4.生成含数据分析功能的防伪编码（5A61M0583D2）
            5.智能批量生成带数据分析功能的防伪码
            6.后续补加生成防伪码（5A61M0583D2）
            7.EAN-13条形码批量生成
            8.二维码批量输出
            9.企业粉丝防伪码抽奖
            0.退出系统
        ===============================================================
        说明：通过数字键选择菜单
        ===============================================================    
    \033[0m
    """)


def main():
    global i
    # 通过循环控制用户对程序功能的选择
    while i < 9:
        mainmenu()
        # 输入需要操作的选项
        choice = input("\033[1;32m 请输入你要操作的菜单选项：\033[0m")
        if len(choice) != 0:
            # 验证输入是否非法
            choice = input_validation(choice)
            if choice == 1:
                scode1(str(choice))
            if choice == 2:
                scode2(choice)
            if choice == 3:
                scode3(choice)
            if choice == 4:
                scode4(choice)
            if choice == 5:
                scode5(choice)
            if choice == 6:
                scode6(choice)
            if choice == 7:
                scode7()
            if choice == 8:
                scode8(choice)
            if choice == 9:
                scode9(choice)
            if choice == 0:
                i = 0
                print("正在退出系统")
                break
        else:
            print("\033[1;31;40m 输入非法，请重新输入：\033[0m")
            time.sleep(2)

if __name__ == '__main__':
    main()